home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / email / header.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  9KB  |  314 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __all__ = [
  5.     'Header',
  6.     'decode_header',
  7.     'make_header']
  8. import re
  9. import binascii
  10. import email.quoprimime as email
  11. import email.base64mime as email
  12. from email.errors import HeaderParseError
  13. from email.charset import Charset
  14. NL = '\n'
  15. SPACE = ' '
  16. USPACE = u' '
  17. SPACE8 = ' ' * 8
  18. UEMPTYSTRING = u''
  19. MAXLINELEN = 76
  20. USASCII = Charset('us-ascii')
  21. UTF8 = Charset('utf-8')
  22. ecre = re.compile('\n  =\\?                   # literal =?\n  (?P<charset>[^?]*?)   # non-greedy up to the next ? is the charset\n  \\?                    # literal ?\n  (?P<encoding>[qb])    # either a "q" or a "b", case insensitive\n  \\?                    # literal ?\n  (?P<encoded>.*?)      # non-greedy up to the next ?= is the encoded string\n  \\?=                   # literal ?=\n  (?=[ \\t]|$)           # whitespace or the end of the string\n  ', re.VERBOSE | re.IGNORECASE | re.MULTILINE)
  23. fcre = re.compile('[\\041-\\176]+:$')
  24. _max_append = email.quoprimime._max_append
  25.  
  26. def decode_header(header):
  27.     header = str(header)
  28.     if not ecre.search(header):
  29.         return [
  30.             (header, None)]
  31.     
  32.     decoded = []
  33.     dec = ''
  34.     for line in header.splitlines():
  35.         if not ecre.search(line):
  36.             decoded.append((line, None))
  37.             continue
  38.         
  39.         parts = ecre.split(line)
  40.         while parts:
  41.             unenc = parts.pop(0).strip()
  42.             if unenc:
  43.                 if decoded and decoded[-1][1] is None:
  44.                     decoded[-1] = (decoded[-1][0] + SPACE + unenc, None)
  45.                 else:
  46.                     decoded.append((unenc, None))
  47.             
  48.             if parts:
  49.                 (charset, encoding) = [ s.lower() for s in parts[0:2] ]
  50.                 encoded = parts[2]
  51.                 dec = None
  52.                 [] if encoding == 'q' else []
  53.                 if dec is None:
  54.                     dec = encoded
  55.                 
  56.                 if decoded and decoded[-1][1] == charset:
  57.                     decoded[-1] = (decoded[-1][0] + dec, decoded[-1][1])
  58.                 else:
  59.                     decoded.append((dec, charset))
  60.             
  61.             del parts[0:3]
  62.     
  63.     return decoded
  64.  
  65.  
  66. def make_header(decoded_seq, maxlinelen = None, header_name = None, continuation_ws = ' '):
  67.     h = Header(maxlinelen = maxlinelen, header_name = header_name, continuation_ws = continuation_ws)
  68.     for s, charset in decoded_seq:
  69.         if charset is not None and not isinstance(charset, Charset):
  70.             charset = Charset(charset)
  71.         
  72.         h.append(s, charset)
  73.     
  74.     return h
  75.  
  76.  
  77. class Header:
  78.     
  79.     def __init__(self, s = None, charset = None, maxlinelen = None, header_name = None, continuation_ws = ' ', errors = 'strict'):
  80.         if charset is None:
  81.             charset = USASCII
  82.         
  83.         if not isinstance(charset, Charset):
  84.             charset = Charset(charset)
  85.         
  86.         self._charset = charset
  87.         self._continuation_ws = continuation_ws
  88.         cws_expanded_len = len(continuation_ws.replace('\t', SPACE8))
  89.         self._chunks = []
  90.         if s is not None:
  91.             self.append(s, charset, errors)
  92.         
  93.         if maxlinelen is None:
  94.             maxlinelen = MAXLINELEN
  95.         
  96.         if header_name is None:
  97.             self._firstlinelen = maxlinelen
  98.         else:
  99.             self._firstlinelen = maxlinelen - len(header_name) - 2
  100.         self._maxlinelen = maxlinelen - cws_expanded_len
  101.  
  102.     
  103.     def __str__(self):
  104.         return self.encode()
  105.  
  106.     
  107.     def __unicode__(self):
  108.         uchunks = []
  109.         lastcs = None
  110.         for s, charset in self._chunks:
  111.             nextcs = charset
  112.             if uchunks:
  113.                 if lastcs not in (None, 'us-ascii'):
  114.                     if nextcs in (None, 'us-ascii'):
  115.                         uchunks.append(USPACE)
  116.                         nextcs = None
  117.                     
  118.                 elif nextcs not in (None, 'us-ascii'):
  119.                     uchunks.append(USPACE)
  120.                 
  121.             
  122.             lastcs = nextcs
  123.             uchunks.append(unicode(s, str(charset)))
  124.         
  125.         return UEMPTYSTRING.join(uchunks)
  126.  
  127.     
  128.     def __eq__(self, other):
  129.         return other == self.encode()
  130.  
  131.     
  132.     def __ne__(self, other):
  133.         return not (self == other)
  134.  
  135.     
  136.     def append(self, s, charset = None, errors = 'strict'):
  137.         if charset is None:
  138.             charset = self._charset
  139.         elif not isinstance(charset, Charset):
  140.             charset = Charset(charset)
  141.         
  142.         if charset != '8bit':
  143.             if isinstance(s, str):
  144.                 if not charset.input_codec:
  145.                     pass
  146.                 incodec = 'us-ascii'
  147.                 ustr = unicode(s, incodec, errors)
  148.                 if not charset.output_codec:
  149.                     pass
  150.                 outcodec = 'us-ascii'
  151.                 ustr.encode(outcodec, errors)
  152.             elif isinstance(s, unicode):
  153.                 for charset in (USASCII, charset, UTF8):
  154.                     
  155.                     try:
  156.                         if not charset.output_codec:
  157.                             pass
  158.                         outcodec = 'us-ascii'
  159.                         s = s.encode(outcodec, errors)
  160.                     continue
  161.                     except UnicodeError:
  162.                         continue
  163.                     
  164.  
  165.                 
  166.             
  167.         
  168.         self._chunks.append((s, charset))
  169.  
  170.     
  171.     def _split(self, s, charset, maxlinelen, splitchars):
  172.         splittable = charset.to_splittable(s)
  173.         encoded = charset.from_splittable(splittable, True)
  174.         elen = charset.encoded_header_len(encoded)
  175.         if elen <= maxlinelen:
  176.             return [
  177.                 (encoded, charset)]
  178.         
  179.         if charset == '8bit':
  180.             return [
  181.                 (s, charset)]
  182.         elif charset == 'us-ascii':
  183.             return self._split_ascii(s, charset, maxlinelen, splitchars)
  184.         elif elen == len(s):
  185.             splitpnt = maxlinelen
  186.             first = charset.from_splittable(splittable[:splitpnt], False)
  187.             last = charset.from_splittable(splittable[splitpnt:], False)
  188.         else:
  189.             (first, last) = _binsplit(splittable, charset, maxlinelen)
  190.         fsplittable = charset.to_splittable(first)
  191.         fencoded = charset.from_splittable(fsplittable, True)
  192.         chunk = [
  193.             (fencoded, charset)]
  194.         return chunk + self._split(last, charset, self._maxlinelen, splitchars)
  195.  
  196.     
  197.     def _split_ascii(self, s, charset, firstlen, splitchars):
  198.         chunks = _split_ascii(s, firstlen, self._maxlinelen, self._continuation_ws, splitchars)
  199.         return zip(chunks, [
  200.             charset] * len(chunks))
  201.  
  202.     
  203.     def _encode_chunks(self, newchunks, maxlinelen):
  204.         chunks = []
  205.         for header, charset in newchunks:
  206.             if not header:
  207.                 continue
  208.             
  209.             if charset is None or charset.header_encoding is None:
  210.                 s = header
  211.             else:
  212.                 s = charset.header_encode(header)
  213.             if chunks and chunks[-1].endswith(' '):
  214.                 extra = ''
  215.             else:
  216.                 extra = ' '
  217.             _max_append(chunks, s, maxlinelen, extra)
  218.         
  219.         joiner = NL + self._continuation_ws
  220.         return joiner.join(chunks)
  221.  
  222.     
  223.     def encode(self, splitchars = ';, '):
  224.         newchunks = []
  225.         maxlinelen = self._firstlinelen
  226.         lastlen = 0
  227.         for s, charset in self._chunks:
  228.             targetlen = maxlinelen - lastlen - 1
  229.             if targetlen < charset.encoded_header_len(''):
  230.                 targetlen = maxlinelen
  231.             
  232.             newchunks += self._split(s, charset, targetlen, splitchars)
  233.             (lastchunk, lastcharset) = newchunks[-1]
  234.             lastlen = lastcharset.encoded_header_len(lastchunk)
  235.         
  236.         return self._encode_chunks(newchunks, maxlinelen)
  237.  
  238.  
  239.  
  240. def _split_ascii(s, firstlen, restlen, continuation_ws, splitchars):
  241.     lines = []
  242.     maxlen = firstlen
  243.     for line in s.splitlines():
  244.         line = line.lstrip()
  245.         if len(line) < maxlen:
  246.             lines.append(line)
  247.             maxlen = restlen
  248.             continue
  249.         
  250.         for ch in splitchars:
  251.             if ch in line:
  252.                 break
  253.                 continue
  254.         else:
  255.             maxlen = restlen
  256.         cre = re.compile('%s\\s*' % ch)
  257.         if ch in ';,':
  258.             eol = ch
  259.         else:
  260.             eol = ''
  261.         joiner = eol + ' '
  262.         joinlen = len(joiner)
  263.         wslen = len(continuation_ws.replace('\t', SPACE8))
  264.         this = []
  265.         linelen = 0
  266.         for part in cre.split(line):
  267.             curlen = linelen + max(0, len(this) - 1) * joinlen
  268.             partlen = len(part)
  269.             onfirstline = not lines
  270.             if ch == ' ' and onfirstline and len(this) == 1 and fcre.match(this[0]):
  271.                 this.append(part)
  272.                 linelen += partlen
  273.                 continue
  274.             if curlen + partlen > maxlen:
  275.                 if this:
  276.                     lines.append(joiner.join(this) + eol)
  277.                 
  278.                 if partlen > maxlen and ch != ' ':
  279.                     subl = _split_ascii(part, maxlen, restlen, continuation_ws, ' ')
  280.                     lines.extend(subl[:-1])
  281.                     this = [
  282.                         subl[-1]]
  283.                 else:
  284.                     this = [
  285.                         part]
  286.                 linelen = wslen + len(this[-1])
  287.                 maxlen = restlen
  288.                 continue
  289.             this.append(part)
  290.             linelen += partlen
  291.         
  292.         if this:
  293.             lines.append(joiner.join(this))
  294.             continue
  295.     
  296.     return lines
  297.  
  298.  
  299. def _binsplit(splittable, charset, maxlinelen):
  300.     i = 0
  301.     j = len(splittable)
  302.     while i < j:
  303.         m = i + j + 1 >> 1
  304.         chunk = charset.from_splittable(splittable[:m], True)
  305.         chunklen = charset.encoded_header_len(chunk)
  306.         if chunklen <= maxlinelen:
  307.             i = m
  308.             continue
  309.         j = m - 1
  310.     first = charset.from_splittable(splittable[:i], False)
  311.     last = charset.from_splittable(splittable[i:], False)
  312.     return (first, last)
  313.  
  314.